/*
 *
 */
#include "common.h"
#include "encoding.h"
#include "text.h"
#include "popup.h"
#include "module.h"
#include "module_opened.h"
#include "handlers_module_opened.h"
#include "selector.h"

/****************************************************************************
 * Save a file which current active( loadded in ActiveTextBuffer();
 * **************************************************************************/
gboolean
SaveActiveFile(void)
{
    GtkWidget* pWidgetTextMainTmp = GetWidgetTextMain();
    if ( ! pWidgetTextMainTmp )
        return FALSE;
	GtkTextBuffer * pTextBuf = gtk_text_view_get_buffer(
							GTK_TEXT_VIEW( pWidgetTextMainTmp ));//pWidgetTextActive));
	GtkTextIter start, end;

	module_t * pActiveModule = GetModuleTextMain();//ActiveModule();
	gchar *errMsg=NULL;
	gsize bufferSize=-1;

	if ( pActiveModule )
	{
		if ( ! pActiveModule->modified )
		{
#ifdef HYPERSRC_DEBUG
			g_print("None modified\n");
#endif
			return TRUE;
		}
		gchar * contents=NULL;
		gtk_text_buffer_get_bounds(	pTextBuf,
									&start,
									&end);
		contents = gtk_text_buffer_get_text(	
									pTextBuf,
									&start,
									&end,
									FALSE);
		if ( NULL == contents )
		{
			g_print(_("%s: TextBuffer return NULL"), __func__);
			return FALSE;
		}
		//bufferSize = strlen(contents);

		// convert the line ending
		convert_line_ending(&contents, pActiveModule->lineEnding);
        bufferSize = strlen(contents);
        
		// convert the charset encoding
		do{
		gsize bytes_read, bytes_written;
		GError *error;
		gchar * new_stream = g_convert( contents,
										-1,
										pActiveModule->pCharset?pActiveModule->pCharset:"UTF-8",
										"UTF-8",
										&bytes_read,
										&bytes_written,
										&error);
		if ( NULL == new_stream || bytes_read != bufferSize )
		{
			errMsg = g_strdup_printf(
						_("Convert charset from `%s' to `%s' error.\nError Code: %s"),
						  "UTF-8", pActiveModule->pCharset, error->message);
			Popup(errMsg,_("Error"), FONT_PROPORTIONAL);
			g_free(errMsg);
			g_error_free(error);
			g_free(contents);
			g_free(new_stream);

			return FALSE;
		}

		bufferSize = bytes_written;
		g_free(contents);
		contents = new_stream;

		} while(0);

		gboolean state= 
				 SaveFile(pActiveModule->pModuleName,
				 contents,
				 -1); // bufferSize;
		g_free(contents);

		if ( !state )
			return FALSE;

		return TRUE;
	}
	else
	{
		Popup(_("Buffer empty"), _("Warning"), FONT_PROPORTIONAL);
	}
	return FALSE;
}


/****************************************************************************
 * Save file in `fileName'
 *
 * @param fileName
 * @param stream
 *		  the source, must a ASCIZ file if size= -1
 * @param size
 *		  file size in bytes.
 * @return
 *		  TRUE if successful
 ****************************************************************************/
gboolean
SaveFile(const gchar * fileName,	/* IN */
		 const gchar * stream,		/* IN */
			   gsize   size)		/* IN */
{
	gchar * errMsg=NULL;

	g_assert( NULL != fileName &&
			  NULL != stream
			);
	FILE *fp=NULL;

	// open file
	fp = fopen(fileName, "wt");
	if ( NULL == fp )
	{
		if ( !FileExists(fileName))
		{
			errMsg = g_strdup_printf(_("File `%s' not exist ,\nmaybe Permission Denied!"), fileName);
			Popup(errMsg,_("Cannot Open File"), FONT_PROPORTIONAL);
			g_free(errMsg);
		}
		else
		{
			errMsg = g_strdup_printf(_("Cannot write file `%s' ,\nmay be Permission Denied!"), fileName);
			Popup(errMsg,_("Cannot Open File"), FONT_PROPORTIONAL);
			g_free(errMsg);
		}
		return FALSE;
	}
	// write file
	if ( -1 == size )
	{
		if ( fputs(stream, fp) == EOF )
		{
			errMsg = g_strdup_printf(_("Cannot write file `%s'"), fileName);
			Popup(errMsg, _("Cannot Open File"), FONT_PROPORTIONAL);
			g_free(errMsg);
			fclose(fp);
			return FALSE;
		}
	}
	else
	{
		while ( 0 != size -- )
		{
			fputc(*stream++, fp);
		}
	}
	fclose(fp);
	return TRUE;
}// SaveFile()

/*************************************************************************
 * Check file exists or not
 * @return
 *		TRUE if exists
 *		FALSE if not exists or cannot be read.
 *************************************************************************/
gboolean
FileExists(const gchar *fileName)
{
	FILE * fp=NULL;
	if ( NULL == fileName )
	{
		DebugMsg("%s : fileName is NULL\n",__func__);
		return FALSE;
	}
	fp = fopen(fileName, "r");
	if ( NULL == fp )
		return FALSE;
	else
		return TRUE;
}

/*************************************************************
 * Ask save or not, if YES, then SaveActiveFile
 * @return  ...
 *************************************************************/
gint
AskSaveOrNot()
{
		//Save changes to `file'?
		// No, Cancel, Yes
   if ( IsMainModuleModified())
   {
		module_t * m=NULL;
		m = GetModuleTextMain();
		if ( !m )
		    return 1;
		gint result = RunDialogMessageQuestion(pWidgetMain,
		                                       _("Save changes to `%s' ?"), 
											   m->pModuleName);
		switch (result)
		{
		    gsize size;
		    
			case GTK_RESPONSE_YES:
				SaveActiveFile();
				//SetMainModuleModified(FALSE);
				return GTK_RESPONSE_YES;
				break;
			case GTK_RESPONSE_NO: // reload buffer from file
		        FreeModuleBuffer(m->pModuleName);
		        ModuleBuffer( m->pModuleName, &size);
		        //SetMainModuleModified(FALSE);
		        return GTK_RESPONSE_NO;
				break;
			default: // Cancel
				return GTK_RESPONSE_CANCEL; 
			}
	 }
	 else
	 {
	     // if non-modified, same as CANCEL
	     return GTK_RESPONSE_CANCEL;
	 }
}//AskSaveOrNot()

/******************************************************************************
 * @para    pModule  NULL if new file
 ******************************************************************************/
gboolean
SaveFileAs(const module_t *pModule)
{
	FileInfo  fi1;
    g_print("%s : here\n", __func__);
	if (!pModule)
	{
	    fi1.filename=NULL;
	    fi1.charset=NULL;
	    fi1.charset_flag=FALSE;
	    fi1.lineend=CHAR_LF;
	}
	else
	{
	    fi1.filename=pModule->pModuleName;
	    fi1.charset =pModule->pCharset; // g_strdup(pModule->pCharset);
	    fi1.lineend =pModule->lineEnding;
	    fi1.charset_flag=TRUE;  //init charset in selector dialog
	}
	FileInfo *fi;
	fi = get_fileinfo_from_selector(&fi1, SAVE);
	if (fi)
	{
	    module_t * pNewModule=g_malloc(sizeof(module_t));
	    if ( !pNewModule )
	        return FALSE;
	    pNewModule->pModuleName = g_strdup(fi->filename);
	    pNewModule->pCharset = g_strdup(fi->charset);
	    pNewModule->lineEnding = fi->lineend;
	    pNewModule->pModuleBuffer = GetMainTextViewContents();
	    pNewModule->modified=FALSE;
	    pNewModule->pGslistFuncDef = NULL;
	    pNewModule->pHashFuncTags  = NULL;
	    if (SaveNewFile(pNewModule))
	    {}
	    else
	    {}
	    return TRUE;
	}
	else
	    return FALSE;
}//SaveFileAs()

gchar *
GetMainTextViewContents()
{
    GtkTextIter start, end;
    GtkWidget  *pTextView    = GetWidgetTextMain();
    GtkTextBuffer * pTextBuf = gtk_text_view_get_buffer(
                                GTK_TEXT_VIEW(pTextView));
  
	gchar * contents=NULL;
	gtk_text_buffer_get_bounds(	pTextBuf,
								&start,
								&end);
	contents = gtk_text_buffer_get_text(	
								pTextBuf,
	    						&start,
								&end,
								FALSE);
	if ( NULL == contents )
	{
		g_print(_("%s: TextBuffer return NULL"), __func__);
		return NULL;
	}
	gchar * buf = g_strdup(contents);
	g_free(contents);
	return buf; // UTF-8 encoding
}

gboolean
SaveNewFile(const module_t *pModule)
{
    //先转换编码和行尾，再调用 SaveFile()
	if ( pModule )
	{
	    gchar *contents = g_strdup(pModule->pModuleBuffer);
		// convert the line ending
		convert_line_ending(&contents, pModule->lineEnding);

        gint bufferSize = strlen(contents);
        
		// convert the charset encoding
		do{
		gsize bytes_read, bytes_written;
		GError *error;
		gchar * new_stream = g_convert( contents,
										-1,
										pModule->pCharset?pModule->pCharset:"UTF-8",
										"UTF-8",
										&bytes_read,
										&bytes_written,
										&error);
		if ( NULL == new_stream || bytes_read != bufferSize )
		{
		    gchar *errMsg;
			errMsg = g_strdup_printf(
						_("Convert charset from `%s' to `%s' error.\nError Code: %s"),
						  "UTF-8", pModule->pCharset, error->message);
			Popup(errMsg,_("Error"), FONT_PROPORTIONAL);
			g_free(errMsg);
			g_error_free(error);
			g_free(contents);
			g_free(new_stream);

			return FALSE;
		}

		bufferSize = bytes_written;
		g_free(contents);
		contents = new_stream;

		} while(0);

		gboolean state= 
				 SaveFile(pModule->pModuleName,
				 contents,
				 -1); // bufferSize;
		g_free(contents);

		if ( !state )
			return FALSE;

		return TRUE;
	}
	else
	{
		Popup(_("Buffer empty"), _("Warning"), FONT_PROPORTIONAL);
	}
	return FALSE;
}

